import logging
from django.http import HttpResponse
from rest_framework import viewsets, status
from rest_framework.request import Request
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework_simplejwt.exceptions import InvalidToken
from rest_framework_simplejwt.views import TokenObtainPairView

from py_web.common.auth.MyAuth import MyAuth
from py_web.common.auth.SecurityUtils import isAdmin
from py_web.common.constant.SecurityConstant import AUTHORIZATION, START
from py_web.common.db.BaseModelViewSet import BaseModelViewSet

from py_web.security import SecuritySerialization
from py_web.security.SecuritySerialization import *
from py_web.security.models import *

logger = logging.getLogger('log')


# Create your views here.

# 函数视图没有办法进行dfr simple jwt认证控制
def index(request):
    return HttpResponse("Hello, world. You're at the polls index.")


class TestViewSet(MyAuth, APIView):
    def get(self, request):
        print(request)
        return HttpResponse("Hello, world. You're at the polls TestViewSet.")


# 登录
class Login(TokenObtainPairView):

    def post(self, request: Request, *args, **kwargs) -> Response:
        # 组件认证不需要重写了
        serializer = self.get_serializer(data=request.data)
        try:
            serializer.is_valid(raise_exception=True)
        except Exception as e:
            logger.error(f"用户信息认证失败：{e},{serializer.errors}")
            raise InvalidToken(e.args[0])

        # 认证成功后获取用户信息以及更改jwt名称
        # 继承了GenericAPIView可以直接.data
        username = request.data.get("username")
        try:
            user = User.objects.get(username=username)
            seria = SecuritySerialization.UserSerializer(user).data

            vo = {
                "user": seria,
                "tokenName": AUTHORIZATION,
                "tokenValue": serializer.validated_data.pop("access")
            }


        except Exception as e:
            logger.error(f"用户信息认证失败：{e}")
            return Response("无账户信息", status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        return Response(vo, status=status.HTTP_200_OK)


# 查询用户菜单路由路径
class GetRouters(MyAuth, APIView):

    def get(self, request: Request, *args, **kwargs) -> Response:
        vo = MenusTemp(request)
        if vo:
            return Response(vo, status=status.HTTP_200_OK)
        return Response("无数据", status=status.HTTP_200_OK)


def MenusTemp(request):
    # 获取用户信息以查询菜单路由路径
    userid = request.user.pk
    # 查询menu 结果是tree的形式
    userRole = UserRole.objects.filter(userId=userid)
    userrs = UserRolesSerializer(instance=userRole, many=True).data
    roleIds = []
    if userrs:
        for ur in userrs:
            roleIds.append(ur['roleId'])

    rm = RoleMenu.objects.filter(roleId__in=roleIds)
    rms = RoleMenuSerializer(instance=rm, many=True).data
    menuIds = []
    if rms:
        for rm in rms:
            menuIds.append(rm['menuId'])

    menu = (Menu.objects
            .filter(menuType__in=['C', 'M'], status=START, menuId__in=menuIds)
            .order_by('parentId', 'orderNum'))

    menus = MenuSerializer(menu, many=True).data

    # 构建tree并排序 利用字典内存结构实现树形数据结构
    if menus:
        all: dict = {}
        tree = []
        routes = []
        for m in menus:
            if m['parentId'] == 0:
                # 保证有children这么个字段
                m['children'] = []
                tree.append(m)

            all[m['menuId']] = m
            if m['path']:
                # 组装路由信息
                routes.append({'path': m['path'], 'component': m['component'], 'name': m['name']})

        for m in menus:
            try:
                # 如果查不到会报错
                parent = all[m['parentId']]
            except:
                continue
            try:
                parent['children']
            except:
                parent['children'] = []

            m['children'] = []
            # 组装树信息
            parent['children'].append(m)

        vo = {
            "menus": tree,
            "routeList": routes,
        }
        return vo
